/**
 * Created by Administrator on 2016/11/11.
 */

import {fork, put} from 'redux-saga/effects';
import {takeEvery, takeLatest} from 'redux-saga';
import {fetch} from './fetch.client';

export function buildRoot(options) {
  const sagaArr = [];
  for (let key in options) {
    let value = options[key];
    if (value instanceof Array) {
      for (let item of value) {
        sagaArr.push(createSaga(item));
      }
    } else {
      sagaArr.push(value);
    }
  }
  return function*() {
    for (let saga of sagaArr) {
      yield fork(saga);
    }
  }
}

function bodyHandler(data, type, method) {
  if (method !== 'get' && data) {
    if (type === 'json') {
      return JSON.stringify(data);
    } else if (type === 'from') {
      let pairs = [];
      for (let key of data) {
        pairs.push(key + '=' + data[key]);
      }
      return pairs.join('&');
    }
  }
  return data;
}

export function createSaga(item) {
  return function*() {
    let take = item.takeEvery ? takeEvery : takeLatest;
    yield take(item.action, function*({payload}) {
      let result;
      try {
        let type = item.type || 'json';
        let bodyParser = item.body || bodyHandler;
        result = yield fetch(item.url(payload), createOptions(item.method, type, item.headers, bodyParser(payload, type, item.method)));
      } catch (error) {
        console.log(error);
      }
      if (result.success) {
        yield put({type: `${item.action}_SUCCESS`, result: result.content, payload})
      } else {
        yield put({type: `${item.action}_FAIL`, error: result.errorMsg, payload})
      }
    });
  }
}

function createOptions(method, type, extHeaders, payload) {
  let options = {method};
  options.headers = extHeaders || {
      'Accept': 'application/json',
      'Content-Type': type === 'json' ? 'application/json' : 'application/x-www-form-urlencoded'
    };
  if (method !== 'get') {
    options.body = payload;
  }
  return options;
}
